package cn.topcodes.tcsf.admin.service.impl;

import cn.topcodes.tcsf.admin.service.IntegrityCheckCallback;
import cn.topcodes.tcsf.admin.service.IntegrityCheckRule;
import cn.topcodes.tcsf.admin.service.IntegrityCheckService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 数据完整性检查服务
 */
@Service
public class IntegrityCheckServiceImpl implements IntegrityCheckService {

    /**
     * 完整性检查规则
     */
    private Map<String, IntegrityCheckRule> rules = new HashMap<String, IntegrityCheckRule>();

    private IntegrityCheckCallback callback = null;

    @Override
    public List<IntegrityCheckRule> getRules() {
        List<IntegrityCheckRule> list = new ArrayList<>();
        for(Map.Entry<String, IntegrityCheckRule> entry : rules.entrySet()) {
            list.add(entry.getValue());
        }
        return list;
    }

    /**
     * 添加检查规则
     * @param rule  检查规则
     */
    @Override
    public void addRule(IntegrityCheckRule rule) {
        if(!rules.containsKey(rule.getId())) {
            rules.put(rule.getId(), rule);
        }
    }

    /**
     * 设置回调
     *
     * @param callback
     */
    @Override
    public void setCallback(IntegrityCheckCallback callback) {
        this.callback = callback;
    }

    /**
     * 获取回调
     *
     * @return
     */
    @Override
    public IntegrityCheckCallback getCallback() {
        return this.callback;
    }

    /**
     * 开始检查
     */
    @Async
    @Override
    public void startCheck() {
        StringBuilder sb = new StringBuilder();
        if(callback != null) {
            callback.onStart();
        }
        for(String ruleId : rules.keySet()) {
            checkRule(ruleId);
        }
        if(callback != null) {
            callback.onStop();
        }
    }

    @Override
    public void checkRule(String ruleId) {
        StringBuilder sb = new StringBuilder();
        IntegrityCheckRule rule = this.rules.get(ruleId);
        if(rule != null) {
            if(callback != null) {
                callback.onRuleCheckBefore(rule);
            }
            sb.append(rule.check());
            if(callback != null) {
                callback.onRuleChecked(rule, sb.toString());
            }
        }
    }

    /**
     * 停止检查
     */
    @Override
    public void stopCheck() {

    }

}
